﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JobDemo01.Job
{
    class Publisher : IDisposable
    {
        readonly StreamWriter writer;

        public Publisher(string path)
        {
            writer = new StreamWriter(Path.Join(path, "results.csv"));
            writer.WriteLine(",ix,iy,x,y,name,result,addr. dx, addr. dy,dx,dy,addr. score,score,addr. threshold,threshold");
        }

        public void Publish(PatternResult result)
        {
            if (result.Image.Kind != PatternKind.Mp)
            {
                return;
            }

            var pImg = result.Image;
            var pattern = pImg.Pattern;
            var pixelSize = GetPixelSize(pattern.Reference.ScanSettings);
            var addrPixelSize = GetPixelSize(pattern.Addressing.ScanSettings);
            for (var i = 0; i < result.Values.Length; i++)
            {
                double? addrMatchDx = null, addrMatchDy = null, addrScore = null;
                if (pImg.Addressing != null)
                {
                    addrMatchDx = pImg.Addressing.MatchDx;
                    addrMatchDy = pImg.Addressing.MatchDy;
                    addrScore = pImg.Addressing.Score;
                }

                var name = pattern.CDPoints[i].Name;
                var (_, value) = result.Values[i];
                var c = pImg.Coordinate;
                writer.WriteLine($"{result.Index},{c.X},{c.Y},{c.Dx},{c.Dy},{name},{value}," +
                    $"{FormatAddrMatch(addrMatchDx)},{FormatAddrMatch(addrMatchDy)}," +
                    $"{pImg.MatchDx * pixelSize},{pImg.MatchDy * pixelSize}," +
                    $"{ToString(addrScore)},{pImg.Score}," +
                    $"{pattern.Addressing.Threshold},{pattern.Reference.Threshold}");
            }

            string FormatAddrMatch(double? value)
            {
                if (value.HasValue)
                {
                    return (value * addrPixelSize).ToString();
                }
                else
                {
                    return "-";
                }
            }
        }

        static double GetPixelSize(ScanSettings settings)
        {
            return settings.ScanWidth == 0 ? 0 : settings.FOV / settings.ScanWidth * 1000;
        }

        static string ToString(double? v)
        {
            return v.HasValue ? v.Value.ToString() : "-";
        }

        public void Dispose()
        {
            writer.Dispose();
        }
    }
}
